package com.weblog.config;

import java.util.LinkedHashMap;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.weblog.common.CommonInfo;
import com.weblog.manager.CustomCacheManager;
import com.weblog.manager.CustomSessionManage;
import com.weblog.realm.CuestRealm;

/**
 * Shiro配置类
 * 
 * @author zhw
 *
 */
@Configuration
public class ShiroConfig {
	
	// 配置自定义的RedisSessionDao
	@Bean(value = "redisSessionDao")
	public RedisSessionDao RedisSessionDao() {
		RedisSessionDao redisSessionDao = new RedisSessionDao();
		return redisSessionDao;
	}

	// 配置session会话管理器
	@Bean(value = "defaultWebSessionManager")
	public CustomSessionManage defaultWebSessionManager(
			@Qualifier(value = "redisSessionDao") RedisSessionDao redisSessionDao) {
		CustomSessionManage customSessionManage = new CustomSessionManage();
		customSessionManage.setSessionDAO(redisSessionDao);
		return customSessionManage;
	}

	// 配置shiro缓存管理器
	@Bean(value = "customCacheManager")
	public CustomCacheManager customCacheManager() {
		CustomCacheManager cacheManager = new CustomCacheManager();
		return cacheManager;
	}

	// 配置HashedCredentialsMatcher
	@Bean(value = "hashedCredentialsMatcher")
	public HashedCredentialsMatcher getHashedCredentialsMatcher() {
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		hashedCredentialsMatcher.setHashAlgorithmName(CommonInfo.MD5); // 设置加密方式
		hashedCredentialsMatcher.setHashIterations(CommonInfo.HASH_INTERATIONS);// 设置散列次数
		return hashedCredentialsMatcher;
	}

	// 配置Realm
	@Bean(value = "cuestRealm")
	public CuestRealm getCuestRealm(
			@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher hashedCredentialsMatcher) {
		CuestRealm cuestRealm = new CuestRealm();
		cuestRealm.setCredentialsMatcher(hashedCredentialsMatcher);
		return cuestRealm;
	}

	// 设置shrio的RememberMe
	@Bean(value = "simpleCookie")
	public SimpleCookie simpleCookie() {
		// 设置cookie的名字
		SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
		simpleCookie.setMaxAge(CommonInfo.REMEMBER_TIME_LENGTH);// 设置cookie存活的时间 7天记住我
		return simpleCookie;
	}

	// 设置RememberMeManager
	@Bean(value = "cookieRememberMeManager")
	public CookieRememberMeManager cookieRememberMeManager(@Qualifier(value = "simpleCookie") Cookie cookie) {
		CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
		cookieRememberMeManager.setCookie(cookie);
		return cookieRememberMeManager;
	}

	// 配置SecutityManager
	@Bean(value = "securityManager")
	public SecurityManager getSecurityManager(@Qualifier(value = "cuestRealm") CuestRealm cuestRealm,
			@Qualifier(value = "defaultWebSessionManager") DefaultWebSessionManager defaultWebSessionManager,
			@Qualifier(value = "customCacheManager") CustomCacheManager customCacheManager,
			@Qualifier(value = "cookieRememberMeManager") CookieRememberMeManager cookieRememberMeManager) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(cuestRealm); // 设置自定义的Realm
		securityManager.setSessionManager(defaultWebSessionManager); // 设置自定义的Session会话管理器
		securityManager.setCacheManager(customCacheManager); // 设置自定义的shrio缓存管理器
		securityManager.setRememberMeManager(cookieRememberMeManager);
		return securityManager;
	}

	// 配置ShiroFilter
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(
			@Qualifier(value = "securityManager") SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		shiroFilterFactoryBean.setLoginUrl("/user/login");//登录的URL

		//没有权限的时候跳到的页面
		shiroFilterFactoryBean.setUnauthorizedUrl("/error/403");

		// 配置过滤器链filterChainDefinitionMap必须是LinkedHashMap 因为它必须保证有序
		LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
		
		//不需要认证500错误
		filterChainDefinitionMap.put("/error/500","anon");//500页面错误

		//不需要认证
		filterChainDefinitionMap.put("/user/logout","logout");//页面验证码
		filterChainDefinitionMap.put("/captcha-image","anon");//页面验证码
		filterChainDefinitionMap.put("/user/login", "anon");//用户登录页面
		filterChainDefinitionMap.put("/user/do/login", "anon");//用户登录页面请求
		filterChainDefinitionMap.put("/user/register","anon");//用户注册页面跳转
		filterChainDefinitionMap.put("/user/do/register","anon");//用户注册页面请求
		
		//博客不需要验证
		filterChainDefinitionMap.put("/weblog/index","anon");//博客主页
		
		filterChainDefinitionMap.put("/*", "authc");// authc需要认证
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);// 设置过滤器链
		return shiroFilterFactoryBean;

	}
}
